package boot;

import java.io.IOException;
import java.util.Enumeration;

import javax.microedition.io.Connector;
import javax.microedition.io.file.FileConnection;

import db.DBListener;
import db.DBReader;
import db.Mp3DBRecord;
import files.Files;
import function.Mp3File;
import function.search.EventListener;
import graphics.screens.EvaluationScreen;

public class EvaluationManager {

	private static final String PARENT = Files.BOOT_ROOT + "/Evals";
	private static final int LIST_SIZE = 51;
	
	private String mark;
	private Mp3File[] mp3List;
	private int currentIndex;

	public void startEvaluation() {
		setupFields();
		getMark();
		setupMp3List();
		evaluateCurrentMp3();
	}

	private void setupFields() {
		mark = null;
		mp3List = new Mp3File[LIST_SIZE];
		currentIndex = 0;
	}

	private void getMark() {
		try {
			FileConnection fcParent = (FileConnection) Connector.open(PARENT);
			Enumeration e = fcParent.list("*.mark", true);
			fcParent.close();
			if (e.hasMoreElements()) {
				String markFilename = (String) e.nextElement();
				mark = markFilename.substring(0, markFilename.length() - 5);
			}
		} catch (IOException e) {
			Boot.alertException(e, this, "getMark()");
		}
	}

	private void evaluateCurrentMp3() {
		Mp3File mp3 = mp3List[currentIndex];
		EvaluationScreen screen = new EvaluationScreen(mp3);
		screen.addListener(new EvalEventListener());
		Boot.setDisplay(screen);
		Boot.queueAndPlay(mp3);
	}

	private void setupMp3List() {
		DBReader dbReader = new DBReader(Files.BOOT_ROOT + "/Boot.db");
		dbReader.addListener(new EvalDBListener(dbReader));
		dbReader.readDB();
	}

	private void saveMarkToDisk() {
		deleteMarkFomDisk();
		try {
			FileConnection markFC = (FileConnection) Connector.open(PARENT
					+ "/" + mark + ".mark");
			markFC.create();
			markFC.close();
		} catch (IOException e) {
			Boot.alertException(e, this, "saveMarkToDisk()");
		}
	}

	private void deleteMarkFomDisk() {
		try {
			FileConnection fcParent = (FileConnection) Connector.open(PARENT);
			Enumeration e = fcParent.list("*.mark", true);
			fcParent.close();
			while (e.hasMoreElements()) {
				String markFilename = (String) e.nextElement();
				FileConnection markFC = (FileConnection) Connector.open(PARENT
						+ "/" + markFilename);
				markFC.delete();
				markFC.close();
			}
		} catch (IOException e) {
			Boot.alertException(e, this, "deleteMarkFromDisk()");
		}
	}

	private class EvalDBListener implements DBListener {

		private DBReader reader;
		private int index;
		private boolean isListCreation;
		
		public EvalDBListener() {
			throw new RuntimeException("Forbidden constructor call.");
		}
		
		public EvalDBListener(DBReader aReader) {
			reader = aReader;
			isListCreation = false;
			index = 0;
		}
		
		public void processRecord(Mp3DBRecord record) {
			String currentTitle = record.getTitle();
			if (mark == null) {
				mark = currentTitle;
				saveMarkToDisk();
			}
			if (isListCreation) {
				if (index < LIST_SIZE) {
					mp3List[index] = record.getMp3File();
					index++;
				} else {
					isListCreation = false;
					try {
						reader.stopReading();
					} catch (IOException e) {
						Boot.alertException(e, this, "EvalDBListener.processRecord()");
					}
				}
			} else {
				if (mark.equals(currentTitle)) {
					isListCreation = true;
					mp3List[index] = record.getMp3File();
					index++;
				}
			}
		}

		public void readingDone() {
			// Nothing
		}

	}
	
	private class EvalEventListener implements EventListener {

		public void processEvent(String event) {
			if (EventListener.EVENT_PROCESS_DONE.equals(event)) {
				currentIndex++;
				if (currentIndex < LIST_SIZE) {	
					mark = mp3List[currentIndex].getTitle();
					saveMarkToDisk();					
				}
				
				if (currentIndex < LIST_SIZE - 1) {					
					evaluateCurrentMp3();
				} else {
					Boot.getInstance().readyToGo();
					// Last one just becomes the next mark
				}
			} else if (EventListener.EVENT_PROCESS_CANCELED.equals(event)) {
				Boot.getInstance().readyToGo();
			}
		}
		
	}
}
